#! /usr/bin/env python
"""
DO NOT RUN
This isn't usable at all, but it's a start. 

Expect a lot of typos 

It contains pythonizations of the 4 classes in the /main directory
Variables and function names are kept the samefor clarity (except for toString2() --> str2())
Once it runs, however, it will be tidied up. In the meantime, leave redundant functions alone 
DONE: /entity, /main
TODO:
Priority:               Folder             File
3                       /inference         StructuralRules.java
                                           SyllogisticRules.java
1                       /gui               ALL (9)
2                       /language          ALL (35)  

/gui will have to be changed, as we won't have a gui
#$$ was to mark self.[memory,center,record,etc], but we later made them global

Supers also have been a bit of an issue... 
#@@ preceed them but should be good for the most part
#@@@ lines still aren't fixed, though

MAJOR CHANGES FROM JAVA:
"and" and "or" are python keywords, so utilityFunctions.[and, or] is now ....[uand, uor]
"""

#/entity
#Base.java
#This needs some cleaning up
class Base(object):
    def __init__(self, first=None, second=None):
        self.current = 0
        self.MAXLENGTH = parameters.MAXMUM_LABEL_RECORD_LENGTH
        self.opener = symbols.Base_opener
        self.closer = symbols.Base_closer
        self.separator = symbols.Base_separator
        self.separator0 = symbols.Base_separator0
        self.length = 0
        self.list = []
        if(first == None):
            self.length = 1
            self.list = [self.current]
        else:
            i1 = 0
            i2 = 0
            j = 0
            while(i2 < second.length() & j < self.MAXLENGTH):
                self.list[j] = first.list[i1]
                i1 += 1
                j += 1
                self.list[j] = second.list[i2]
                i2 += 1
                j += 1
            while(i1<first.length() & j < self.MAXLENGTH):
                self.list[j] = first.list[i1]
                i1 += 1
                j += 1
            self.length = j
        
    def length(self):
        return self.length
    def listItem(self, i): #AKA list(i) in code
        return self.list[i] #Just use list[i] instead
    def include(self, s):
        result = False
        if (self.length >= s.length()):
            for i in range(s.length()):
                result = False
                for j in range(self.length):
                    if(self.list[j] == s.list[i]):
                        result = True
                        break
                if (result == False):
                    break
        return result
    def equals(that):
        return (isinstance(that, Base) & self.include(that) & that.include(self))  
    def latest(self):
        v = self.list[0]
        for i in list:
            if (i > v):
                v = i
        return v
    def __str__(self):
        buf = self.opener + self.length + self.separator0
        for i in range(self.length):
            buf += list[1]
            if (i < self.length - 1):
                buf += self.separator
            else:
                buf += self.closer

#BudgetValue.java
class BudgetValue(object):
    # s/ShortFloat()//
    def __init__(self, a=None, b=0.01, c=0.01):
        self.mark = symbols.BUDGET_VALUE_MARK
        self.separator = symbols.VALUE_SEPARATOR
        if(type(a) == type(0.01)):
            self.priority = a
            self.durabilty = b
            self.quality = c
        elif(type(a) == type(self)):
            self.priority = a.priority()
            self.durability = b.durability()
            self.quality = c.quality()
        else:
            self.priority = 0.01
            self.durability = 0.01
            self.quality = 0.01
    def clone(self):
        return BudgetValue(self)
    def merge(self, that):
        return budgetFunctions.merge(self, that)
    def singleValue(self):
        return utilityFunctions.aveAri(self.priority, self.durability, self.quality)
    def aboveThreshold(self):
        return (self.singleValue() > 0.001)
    def __str__(self):
        return "%s%s%s%s%s%s%s" % (self.mark, self.priority, self.separator, self.durability, self.separator, self.quality, self.mark)
#Item.java -- out of alpha order because classes before it inherit it
class Item(BudgetValue):
    def __init__(self, v=None):
        if(v != None):
            #@@
            super(Item, self).__init__(self, v)
        self.key = ""   
    def getKey(self):
        return self.key
    def setKey(self, k):
        self.key = k
    def getBudget(self):
        return self
    def setBudget(self, v):
        self.priority = v.priority
        self.durability = v.durability
        self.quality = v. quality  
#Concept.java
class Concept(Item):
    def __init__(self, tm): 
        #@@
        super(Concept, self).__init__()
        self.directBeliefs = []
        self.directGoals = []
        self.directQuestion = None
        self.revisible = True
        self.linkTemplates = []
        self.taskLinks = TaskLinkBag()
        self.termLinks = TermLinkBag()
        self.showing = False
        self.window = None
        self.term = tm
        self.key = str(tm)
        if (isinstance(tm, CompoundTerm)):
            self.linkTemplates = tm.prepareComponentLinks()
            self.checkRevisibility()
    def checkRevisibility(self):
        self.revisible = not isinstance(self.term, Tense)
        if(self.revisible):
           self.revisible = ((key.index("()") < 0) & (key.index("(#") < 0))
    def processGoal(self, task):
        goal = task.getSentence()
        if (revisible):
            self.reviseTable(task, self.directGoals)   
        else:
            self.updateTable(task)
        for judg in self.directBeliefs:
            matchingRules.trySolution(goal, judg, task)
        if (task.getPriority() > 0):
            self.addToTable(goal, self.directGoals, parameters.MAXMUM_GOALS_LENGTH)
        self.decisionMaking(task)
    def decisionMaking(self, task):
        goal = task.getSentence()
        desire = 2 * goal.getTruth().getExpectation() - 1
        quality = 0
        if (desire > 0):
            quality = desire
        task.quality = quality
    def reviseTable(self, task, table):
        for belief in table:
            if(belief.noOverlapping(task.getSentence())):
                matchingRules.revision(task, belief, False)
    #TODO: the java version is "To be rewritten", and currently commentted out
    #Update after revision
    def updateTable(self, task):
        for belief in self.directBeliefs:
            if (task.getSentence().getBase().latest() > belief.getBase().latest()):
                matchingRules.update(task, belief)
    def addToTable(self, newJudgment, table, capacity):
        rank1 = budgetFunctions.rankBelief(newJudgment)
        base1 = newJudgment.getBase()
        for judgment2 in table:
            rank2 = budgetFunctions.rankBelief(newJudgment)
            if(rank1 >= rank2):
                if(newJudgment.equivalentTo(judgment2)):
                    return
                i = table.index(judgement2)
                table[i] = newJudgment
                break
        if(len(table) == capacity):
            table.pop()
        else: #I don't see a point for the condition... "(i == table.size())" line 206
            table.append(newJudgment)
    def getBelief(self, task):
        sentence = task.getSentence()
        for belief in self.directBeliefs:
            if (isinstance(sentence, Question) or belief.noOverlapping(sentence)):
                #$$
                record.append(" * Selected Belief: %s" % belief)
                return belief
        return None
    def getTermLinks(self):
        return self.linkTemplates
    def insertTaskLink(self, taskLink):
        budget = taskLink.getBudget()
        self.taskLinks.putIn(taskLink)
        #$$
        memory.activateConcept(self, budget)
        if (isinstance(this.term, CompoundTerm)):
            self.buildTermLinks(budget)
    def buildTermLinks(budget):
        subBudget = budgetFunctions.distributeAmongLinks(budget, len(self.linkTemplates))
        if (not subBudget.aboveThreshold()):
            return
        for link in linkTemplates:
            t = link.getTarget()
            #$$
            c = memory.getConcept(t)
            cLink1 = TermLink(t, link, subBudget)
            self.insertTermLink(cLink1)
            cLink2 = TermLink(self.term, link, subBudget)
            self.insertTermLink(cLink2)
            if (isinstance(t, CompoundTerm)):
                c.buildTermLinks(subBudget)
    def insertTermLink(self, cLink):
        self.termLinks.putIn(cLink)
        #$$
        memory.activateConcept(self, cLink.getBudget())
    #Main Loop
    def fire(self):
        #$$-palooza There are about 10 instances here
        tLink = taskLinks.takeOut()
        if (tLink == None):
            return
        memory.currentTaskLink = tLink
        memory.currentBeliefLink = None
        if (nars.isStandAlone()):
            record.append(" * Selected TaskLink: %s\n" %tLink)
        task = tLink.getTargetTask()
        record.append(" * Selected Task: %s\n" % task)
        memory.currentTask = task
        
        if ((tLink.getType() == termLink.TRANSFORM) & (not task.isStructual())):
            ruleTables.transformTask(task, tLink)
            return
        bLink = self.termLinks.takeOut(tLink)
        if (bLink != None):
            if (nars.isStandAlone()):
                record.append(" * Selected BeliefLink: %s\n" % bLink)
            memory.currentBeliefLink = bLink
            ruleTables.reason(tLink, bLink)
            self.termLinks.putBack(bLink)
        self.taskLinks.putBack(tLink)
    #utility & display
    def getTerm(self):
        return self.term
    def __str__(self):
        if (nars.isStandAlone()):
            #@@
            return "%s %s" % (super(Concept, self).__str__(self), self.key) 
        else:
            return self.key
    def getQuality(self):
        return utilityFunctions.uand(self.taskLinks.averagePriority(), self.termLinks.averagePriority())
    def startPlay(self):
        self.window = ConceptWindow(self)
        self.showing = true
        self.window.post(self.displayContent())
        self.taskLinks.startPlay("Task Links in " % self.term)
        self.termLinks.startPlay("Term Links in " % self.term)
    def play(self):
        self.showing = True
        self.window.post(self.displayContent())
    def stop(self):
        self.showing = False
    def displayContent(self):
        buf = "" #buffer
        if(len(self.directBeliefs) > 0):
            buf += "  Beliefs:\n"
            for belief in self.directBeliefs:
                buf += "%s\n" % belief
        if(len(self.directGoals) > 0):
            buf += "\n  Goals:\n"
            for goal in self.directGoals:
                buf += "%s\n" % belief
        if(self.directQuestion != None):
            buf += "\n Question:\n%s\n" % self.directQuestion
        return buf
#Sentence.java -- out of alpha
class Sentence(object):
    def __init__(self):
        self.content = None
        self.truth = None
        self.base = None
        self.input = False
        self.bestSolution = None
    def make(self, a, b, truth, base):
        #Pseudo-overloading
        if(type(b) == type(" ")):
            term = a
            punc = b
            if(isinstance(term, CompoundTerm)):
                term.renameVariables()
            if(punc == symbols.JUDGMENT_MARK):
                return Judgment(term, punc, truth, base)
            elif(punc == symbols.GOAL_MARK):
                return Goal(term, punc, truth, base)
            elif(punc == symbols.QUESTION_MARK):
                return Question(term, punc)
            else:
                return None
        else:
            term = b
            oldS = a
            if(isinstance(term, CompoundTerm)):
                term.renameVariables()
            if(isinstance(oldS, Question)):
                return Question(term, symbols.QUESTION_MARK, truth, base)
            if(isinstance(oldS, Goal)):
                return Goal(term, symbols.JUDGMENT_MARK, truth, base)
    def getContent(self):
        return self.content
    def cloneContent(self):
        return content.clone()
    def getTruth(self):
        return None
    def getBase(self):
        return None
    def isJudgment(self):
        return (self.punctuation == symbols.JUDGMENT_MARK)
    def isInput(self):
        return self.input
    def setInput(self): 
        self.input = True
    def getBestSolution(self):
        return self.bestSolution
    def setBestSolution(self, j):
        self.bestSolution = j
        if (self.input):
            #$$
            memory.report(j, False)
    def __str__(self):
        s = "%s%s " % (self.content.getName(), self.punctuation)
        if (self.truth != None):
            s += str(truth)
            #$$
            if (nars.isStandAlone()):
                s += str(self.base)
        if (nars.isStandAlone()):
            if (self.bestSolution != None):
                s += "BestSolution: %s" % self.bestSolution
        return s
    def str2(self):
        return str(self)
#Judgment.java -- out of alpha
class Judgment(Sentence):
    def __init__(self, term, punc, t, b):
        Sentence.__init__()
        self.content = term
        self.punctuation = punc
        self.truth = t
        self.base = b
    def getTruth(self):
        return self.truth
    def getFrequency(self):
        return self.truth.getFrequency()
    def getConfidence(self):
        return self.truth.getConfidence()
    def getBase(self):
        return self.base
    def equivalentTo(self, judgment2):
        return (self.truth.equals(judgment2.getTruth()) & self.base.equals(judgment2.getBase())) #"May have different key"
    def getExpectationDifference(self, that):
        return self.getTruth().getExpDifAbs(that.getTruth)
    def solutionQuality(self, sentence):
        problem = sentence.getContent()
        if(isinstance(sentence, Goal)):
            return self.truth.getExpectation()
        elif(problem.isConstant()):
            return self.truth.getConfidence()
        else:
            return self.truth.getExpectation() / self.content.getComplexity()
    def noOverlapping(self, judgment):
        b = Base.make(base, judgment.getBase())
        if (b == None):
            return False
        #$$
        memory.currentBase = b
        return True
#Goal.java -- incredibly long, so hold on
class Goal(Judgment):
    def __init__(self, term, punc, t, b):
        Judgment.__init__(term, punc, t, b)
#Item.java -- see above
#Judgment.java -- see above
#Question.java -- This one is *actually* long... really
class Question(Sentence):
    def __init__(self, term, punc):
        Sentence.__init__()
        self.content = term
        self.punctuation = punc
#Sentence.java -- see above
#ShortFloat.java has no need to be implemented
#Task.java
class Task(Item):
    def __init__(self, s, b):
        self.structual = False
        self.sentence = s
        #@@
        super(Task, self).__init__(self, b)
        self.key = str(sentence)
    def getSentence(self):
        return self.sentence
    def getContent(self):
        return self.sentence.getContent()
    def isStructual(self):
        return self.structual
    def setStructual(self):
        self.structual = True
    def merge(that):
        super(Task, self).merge(that.getBudget())
        self.structual = (self.structual or that.Task.isStructual())
    def __str__(self):
        s = ""
        if (nars.isStandAlone()):
            s += super(Task, self).__str__(self)
        s += self.sentence
        return s
    def str2(self):
        s = ""
        if (nars.isStandAlone()):
            s += super(Task, self).__str__(self)
        if (isinstance(self.sentence, Question)):
            s += self.sentence
        else:
            s += str2(self.sentence.Judgment)
        return s
#TermLink.java -- out of alpha
class TermLink(Item):
    def __init__(self, t, p=None, i=None,j=None,k=None):
        self.SELF = 0
        self.COMPONENT = 1
        self.COMPOUND = 2
        self.COMPONENT_STATEMENT = 3
        self.COMPOUND_STATEMENT = 4
        self.COMPONENT_CONDITION = 5
        self.COMPOUND_CONDITION = 6
        self.TRANSFORM = 7
        self.index = None
        self.type = None
        self.target = None
        
        if (p != None & (not isinstance(p, TermLink))):
            self.type = p
            self.target = t
            self.index = []
            self.index[0] = i
            self.setKey()
            if(j != None):
                self.index[1] = j
            if(k != None):
                self.index[2] = k
        elif(p == None):
            #@@
            super(TermLink, self).__init__(self, t)
        else:
            #@@
            super(TermLink, self).__init__(self, i)
            self.target = t
            self.type = p.getType()
            if (p.getTarget().equals(self.getTarget)):
                self.type = self.reverse(self.type)
            self.index = p.getIndices()
            self.setKey()
    def setKey(self):
        if(self.toComponent()):
            at1 = symbols.LinkToComponent_at1
            at2 = symbols.LinkToComponent_at2
        else:
            at1 = symbols.LinkToCompound_at1
            at2 = symbols.LinkToCompound_at2
        i = "T%s" % self.type
        if( self.index != None):
            for x in index:
                i += "-%s" % (x+1)
        self.key = "%s%s%s" % (at1, i, at2)
        if (self.target != None):
            self.key += self.target
    def getTarget(self):
        return self.target
    def getType(self):
        return self.type
    def toComponent(self):
        return ((self.type % 2) > 0)
    def indexLength(self):
        if(self.index == None):
            return 0
        return len(self.index)
    def getIndices(self):
        return self.index
    def getIndex(self, i):
        if (self.index != None & i < len(self.index)):
            return self.index[i]
        else:
            return -1
    def reverse(self, i):
        if ((i % 2) == 0):
            return i - 1
        return i + 1
    def __str__(self):
        #@@
        return super(TermLink, self).__str__(self) + self.key
    def str2(self):
        #@@
        return super(TermLink, self).str2(self) + self.key
#TaskLink.java
class TaskLink(TermLink):
    def __init__(self, t, template, v):
        record_LENGTH = parameters.TASK_INFERENCE_RECORD_LENGTH
        record = []
        #@@
        super(TaskLink, self).__init__(self, v)
        if (template == None):
            self.type = TermLink.SELF
            self.index = None
        else:
            self.type = template.getType()
            self.index = template.getIndices()
        self.targetTask = t
        self.setKey()
        self.key += t.getKey()
    def getTargetTask(self):
        return self.targetTask
    def getRecord(self):
        return record
    def merge(that):
        #@@@
        self.TermLink.Item.BudgetValue.merge(that.getBudget())
        #@@@
        v = that.TaskLink.getRecord()
        this.record += v
    def novel(bLink):
        bTerm = bLink.getTarget()
        if (bTerm.equals(self.targetTask.getSentence().getContent())):
            return False
        key = bLink.getKey()
        for record in record:
            if (key.equals(str(record))):
                return False
        record.append(key)
        return True
#TermLink.java -- see above
#TruthValue.java
class TruthValue(object):
    def __init__(self, f, c):
        self.DELIMITER = symbols.TRUTH_VALUE_MARK
        self.SEPARATOR = symbols.VALUE_SEPARATOR
        self.frequency = None
        self.confidence = None
        if(isinstance(f, TruthValue)):
            v = f
            self.frequency = v.getFrequency()
            self.confidence = v.getConfidence()
        else:
            self.frequency = f
            self.confidence = c
    def getFrequency(self):
        return self.frequency
    def getConfidence(self):
        return self.confidence
    def getExpectation(self):
        return (self.confidence * (self.frequency - 0.50) + 0.50)
    def getExpDifAbs(self, e):
        if(isinstance(e, TruthValue)):
            return self.getExpDifAbs(e.getExpectation)
        return abs(e - self.getExpectation)
    def equals(self, that):
        return ((isinstance(that, TruthValue)) &
                (self.getFrequency() == that.getFrequency()) &
                (self.getConfidence() == that.getConfidence()))
    def __str__(self):
        return "%s%s%s%s%s" % (self.DELIMETER, self.frequency, self.SEPARATOR, self.confidence, self.DELIMETER)
    def str2(self):
        return str(self) 
        
#/inference
#RuleTables.java
class RuleTables(object):
    def reason(self, tLink, bLink):
        task = memory.currentTask
        taskTerm = task.getContent().clone()
        beliefTerm = bLink.getTarget().clone()
        beliefConcept = memory.termToConcept(beliefTerm)
        belief = None
        if (beliefConcept != None):
            belief = beliefConcept.getBelief(task)
        memory.currentBelief = belief
        if ((belief != None) and (variable.findSubstitute(variable.VarType.QUERY, taskTerm, beliefTerm) != None)):
            matchingRules.match(task, belief)
        tIndex = tLink.getIndex(0)
        bIndex = tLink.getIndex(0)
        #JAVA: To be revised
        if (tLink.getType() == termLink.SELF):
            if (bLink.getType() == termLink.COMPONENT):
                self.compoundAndSelf(taskTerm, beliefTerm, True)
            elif (bLink.getType() == termLink.COMPOUND):
                self.compoundAndSelf(beliefTerm, taskTerm, False)
            elif (bLink.getType() == termLink.COMPONENT_STATEMENT):
                if (belief != None):
                    syllogisticRules.detachment(taskTerm, None, True, bIndex)
            elif (bLink.getType() == termLink.COMPOUND_STATEMENT):
                if (belief != None):
                    syllogisticRules.detachment(beliefTerm, None, False, bIndex)
            elif (bLink.getType() == termLink.COMPONENT_CONDITION):
                if (belief != None):
                    syllogisticRules.conditionalDedInd(taskTerm, bIndex, beliefTerm, tIndex)
            elif (bLink.getType() == termLink.COMPOUND_CONDITION):
                if (belief != None):
                    syllogisticRules.conditionalDedInd(beliefTerm, bIndex, taskTerm, tIndex)
        elif (tLink.getType() == termLink.COMPOUND):
            if (bLink.getType() == termLink.COMPOUND):
                self.compoundAndCompound(taskTerm, tIndex, beliefTerm, bIndex)
            elif (bLink.getType() == termLink.COMPOUND_STATEMENT):
                self.compoundAndStatement(taskTerm, tIndex, beliefTerm, bIndex, beliefTerm)
        elif (tLink.getType() == termLink.COMPOUND_STATEMENT):
            if (bLink.getType() == termLink.COMPONENT):
                self.componentAndStatement(memory.currentTerm, bIndex, taskTerm, tIndex)
            elif (bLink.getType() == termLink.COMPOUND):
                self.compoundAndStatement(beliefTerm, bIndex, taskTerm, tIndex, beliefTerm)
            elif (bLink.getType() == termLink.COMPOUND_STATEMENT):
                if (belief != None):
                    self.syllogisms(tLink, bLink, taskTerm, beliefTerm)
            elif (bLink.getType() == termLink.COMPOUND_CONDITION):
                if (belief != None):
                    self.conditionalDedIndWithVar(beliefTerm, bIndex, taskTerm, tIndex)
        elif (tLink.getType() == termLink.COMPOUND_CONDITION):
            if (bLink.getType() == termLink.COMPOUND_STATEMENT):
                if (belief != None):
                    self.conditionalDedIndWithVar(taskTerm, tIndex, beliefTerm, bIndex)
    def syllogisms(self, tLink, bLink, taskTerm, beliefTerm):
        sentence = memory.currentTask.getSentence()
        belief = memory.currentBelief
        figure = 0
        if (isinstance(taskTerm, Inheritance)):
            if (isinstance(beliefTerm, Inheritance)):
                figure = self.indexToFigure(tLink, bLink)
                self.asymmetricAsymmetric(sentence, belief, figure)
            elif (isinstance(beliefTerm, Similarity)):
                figure = self.indexToFigure(tLink, bLink)
                self.asymmetricSymmetric(sentence, belief, figure)
            else:
                self.detachmentWithVar(beliefTerm, False, bLink.getIndex(0), taskTerm, belief)
        elif (isinstance(taskTerm, Similarity)):
            if (isinstance(beliefTerm, Inheritance)):
                figure = self.indexToFigure(bLink, tLink)
                self.asymmetricSymmetric(belief, sentence, figure)
            elif (isinstance(beliefTerm, Similarity)):
                figure = self.indexToFigure(bLink, tLink)
                self.symmetricSymmetric(belief, sentence, figure)
        elif (isinstance(taskTerm, Implication)):
            if (isinstance(beliefTerm, Implication)):
                figure = self.indexToFigure(tLink, bLink)
                self.asymmetricAsymmetric(sentence, belief, figure)
            elif (isinstance(beliefTerm, Equivalence)):
                figure = self.indexToFigure(tLink, bLink)
                self.asymmetricSymmetric(sentence, belief, figure)
            elif (isinstance(beliefTerm, Inheritance)):
                self.detachmentWithVar(taskTerm, True, tLink.getIndex(0), beliefTerm, belief)
        elif (isinstance(taskTerm, Equivalence)):
            if (isinstance(beliefTerm, Implication)):
                figure = self.indexToFigure(bLink, tLink)
                self.asymmetricSymmetric(belief, sentence, figure)
            elif (isinstance(beliefTerm, Equivalence)):
                figure = self.indexToFigure(bLink, tLink)
                self.symmetricSymmetric(belief, sentence, figure)
            elif (isinstance(beliefTerm, Inheritance)):
                self.detachmentWithVar(taskTerm, True, tLink.getIndex(0), beliefTerm, belief)
                
    def indexToFigure(self, link1, link2):
        return (link1.getIndex(0) + 1) * 10 + (link2.getIndex(0) + 1) #returns 11,12,21,22
    def asymmetricAsymmetric(self, sentence, belief, figure):
        asymSt = asym.cloneContent()
        symSt = sym.cloneContent()
        if (figure == 11):
            if (variable.unify(variable.VarType.INDEPENDENT, asymSt.getSubject(), symSt.getSubject(), asymSt, symSt)):
                t1 = asymSt.getPredicate()
                t2 = symSt.getPredicate()
                if (variable.unify(variable.VarType.QUERY, t1, t2, asymSt, symSt)):
                    matchingRules.matchAsymSym(asym, sym, figure)
                else:
                    syllogisticRules.analogy(t2, t1, asym, sym)
        elif (figure == 12):
            if (variable.unify(variable.VarType.INDEPENDENT, asymSt.getSubject(), symSt.getPredicate(), asymSt, symSt)):
                t1 = asymSt.getPredicate()
                t2 = asymSt.getSubject
                if (variable.unify(variable.VarType.QUERY, t1, t2, asymSt, symSt)):
                    matchingRules.matchAsymSym(asym, sym, figure)
                else:
                    syllogisticRules.analogy(t2, t1, asym, sym, figure)
        elif (figure == 21):
            if (variable.unify(variable.VarType.INDEPENDENT, asymSt.getPredicate(), symSt.getSubject(), asymSt, symSt)):
                t1 = asymSt.getSubject()
                t2 = symSt.getPredicate()
                if (variable.unify(variable.VarType.QUERY, t1, t2, asymSt, symSt)):
                    matchingRules.matchAsymSym(asym, sym, figure)
                else:
                    syllogisticRules.analogy(t1, t2, asym, sym)
        elif (figure == 22):
            if (variable.unify(variable.VarType.INDEPENDENT, asymSt.getPredicate(), symSt.getPredicate(), asymSt, symSt)):
                t1 = asymSt.getPredicate()
                t2 = symSt.getPredicate()
                if (variable.unify(variable.VarType.QUERY, t1, t2, asymSt, symSt)):
                    matchingRules.matchAsymSym(asym, sym, figure)
                else:
                    syllogisticRules.analogy(t1, t2, asym, sym)
    def symmetricSymmetric(self, belief, sentence, figure):
        s1 = belief.cloneContent()
        s2 = sentence.cloneContent()
        if (figure == 11):
            if (variable.unify(variable.VarType.INDEPENDENT, s1.getSubject(), s2.getSubject, s1, s2)):
                syllogisticRules.resemblance(s1.getPredicate(), s2.getPredicate(), belief, sentence, figure)
        elif (figure == 12):
            if (variable.unify(variable.VarType.INDEPENDENT, s1.getSubject(), s2.getPredicate, s1, s2)):
                syllogisticRules.resemblance(s1.getSubject(), s2.getSubject(), belief, sentence, figure)
        elif (figure == 21):
            if (variable.unify(variable.VarType.INDEPENDENT, s1.getPredicate(), s2.getSubject, s1, s2)):
                syllogisticRules.resemblance(s1.getSubject(), s2.getPredicate(), belief, sentence, figure)
        elif (figure == 22):
            if (variable.unify(variable.VarType.INDEPENDENT, s1.getPredicate(), s2.getPredicate, s1, s2)):
                syllogisticRules.resemblance(s1.getSubject(), s2.getSubject(), belief, sentence, figure)
    def detachmentWithVar(self, statement, compoundTask, index, compound, belief):
        component = statement.componentAt(index)
        if (isinstance(compound, Tense)):
            inh = componentAt(0)
        else:
            inh = compound
        if (isinstance(component, Inheritance) and (belief != None)):
            if (component.isConstance()):
                syloogisticRules.detachment(statement, compound, compoundTask, index)
            elif (variable.unify(variable.VarType.INDEPENDENT, component, inh, statement, compound)):
                syllogisticRules.detachment(statement, compound, compoundTask, index)
            elif (isinstance(statement, Implication) and (memory.currentTask.getSentence().isJudgment())):
                syllogisticRules.introVarIndInner(statement, statement.getPredicate(), inh)
                compositionalRules.introVarDepInner(statement, statement.getPredicate(), inh)
    def conditionalDedIndWithVar(self, conditional, index, statement, side):
        condition = conditional.getSubject()
        component = condition.componentAt(index)
        component2 = None
        if (isinstance(statement, Inheritance)):
            component2 = statement
        elif (isinstance(statement, Implication)):
            component2 = statement.componentAt(side)
        if ((component2 != None) and variable.unify(variable.VarType.INDEPENDENT, component, component2, conditional, statement)):
            syllogisticRules.conditionalDedIn(conditional, index, statement, -1)
    def compoundAndSelf(self, compound, component, compoundTask):
        if (isinstance(compound, Conjunction) or isinstance(compound, Disjunction)):
            if (memory.currentBelief != None):
                compositionalRules.decomposeStatement(compound, component, compoundTask)
            elif (compound.containComponent(component)):
                structuralRules.structuralCompound(compound, component, compoundTask)
        elif (isinstance(compound, Negation) and not memory.currentTask.isStructual()):
            if (compoundTask):
                structuralRules.transformNegation(compound.componentAt(0))
            else:
                structuralRules.transformNegation(compound)
    def compoundAndCompound(taskTerm, tIndex, beliefTerm, bIndex):
        if (taskTerm.getClass() == beliefTerm.getClass()):
            if (taskTerm.size() > beliefTerm.size()):
                self.compoundAndSelf(taskTerm, beliefTerm, True)
            elif (taskTerm.size() < beliefTerm.size()):
                self.compoundAndSelf(beliefTerm, taskTerm, False)
    def compoundAndStatement(compound, index, statement, side, beliefTerm):
        compound = compound.componentAt(index)
        task = memory.currentTask
        if (component.getClass() == statement.getClass()):
            if (isinstance(compound, Conjunction) and (memory.currentBelief != None)):
                if (variable.unify(variable.VarType.DEPENDANT, component, statement, compound, statement)):
                    compositionalRules.abdVarDepOuter(compound, component, statement.equals(beliefTerm))
                elif (task.getSentence().isJudgment()):
                    syllogisticRules.introVarIndInner(compound, component, statement)
                    compositionalRules.introVarDepInner(compound, component, statement)
        else:
            if (isinstance(compound, Tense)):
                if (isinstance(component, Inheritance)):
                    self.detachmentWithVar(statement, statement.equals(beliefTerm), side, compound, Memory.currentBelief)
                else:
                    belief = memory.currentBelief
                    if (belief != None):
                        syllogisticRules.detachment(statement, compound, statement.equals(beliefTerm), side)
            elif (not task.isStructual() and task.getSentence().isJudgment()):
                if (isinstance(statement, Inheritance)):
                    structuralRules.structuralCompose1(compound, index, statement)
                    if (not isinstance(compound, SetExt) and not isinstance(compound, SetInt)):
                        structuralRules.structuralCompose2(compound, index, statement, side)
                elif (isinstance(statement, Similarity)):
                    structuralRules.structuralCompose2(compound, index, statement, side)
    def componentAndStatement(self, compound, index, statement, side):
        if (not memory.currentTask.isStructual()):
            if (isinstance(statement, InheritAnce)):
                structuralRules.structuralDecompose1(compound, index, statement, side)
                if (not isinstance(compound, SetExt) and not isinstance(compound, SetInt)):
                    structuralRules.structuralDecompose2(statment)
                else:
                    structuralRules.transformSetRelation(compound, statement, side)
            elif (isinstance(statement, Similarity)):
                structuralRules.structuralDecompose2(statement)
                if (isinstance(compound, SetExt) or isinstance(compound, SetInt)):
                    structuralRules.transformSetRelation(compound, statement, side)
            elif (isinstance(statement, Implication) and isinstance(compound, Negation)):
                structuralRules.contraposition(statement)
    def transformTask(self, task, tLink):
        content = task.getContent().clone()
        indices = tLink.getIndices()
        inh = None
        if (len(indices) == 2):
            inh = content
        elif (len(indices) == 3):
            if (isinstance(content, Implication) and isinstance(content.componentAt(0), Conjunction)):
                inh = content.componentAt(0).componentAt(indices[0])
            else:
                inh = content.componentAt(indices[0])
        if (isinstance(inh, Inheritance)):
            structuralRules.transformProductImage(inh, content, indices, task)
 
#UtilityFunctions.java -- out of alpha
class UtilityFunctions(object):
    def aveAri(self, arr):
        s = 0.0
        for x in arr:
            s += x
        return s / (len(arr) * 1.0)
    def uor(self, arr): #AKA or()
        p = 1.0
        for x in arr:
            p *= (1 - x)
        return 1 - p
    def uand(self, arr): #AKA and()
        p = 1.0
        for x in arr:
            p *= x
        return p
    def w2c(self, v):
        return v / (v + parameters.NEAR_FUTURE)

#Budget Functions
class BudgetFunctions(UtilityFunctions):
    #def __init__(self):
        #
    def truthToQuality(self, t):
        freq = t.getFrequency()
        conf = t.getConfidence()
        return self.uand(conf, abs(freq-0.5) +freq * 0.5)
    def rankBelief(self, judg):
        confidence = judg.getConfidence()
        originality = 1.0 / (len(judg.getBase()) + 1)
        return uor(confidence, originality)
    def solutionEval(self, problem, solution, task):
        budget = None
        feedbackToLinks = False
        if (task == None):
            #$$
            task = memory.currentTask
            feedbackToLinks = True
        judgmentTask = task.getSentence().isJudgment()
        quality = 0.0
        if (isinstance(problem, Question)):
            quality = solution.solutionQuality(problem)
        else:
            quality = solution.getTruth().getExpectation()
        if (judgmentTask):
            task.inPriority(quality)
        else:
            task.setPriority(min(1-quality, task.getPriority))
        if (feedbackToLinks):
            #$$
            tLink = memory.currentTaskLink
            tLink.setPriority(min(1-quality, tLink.getPriority()))
            bLink = memory.currentBeliefLink
            bLink.incPriority(quality)
        return budget
    def revise(self, tTruth, bTruth, truth, task, feedbackToLinks):
        difT = truth.getExpDifAbs(tTruth)
        task.decPriority(1 - difT)
        task.decDurability(1 - difT)
        if (feedbackToLinks):
            #$$
            tLink = memory.currentTaskLink
            tLink.decPriority(1 - difT)
            tLink.decDurability(1 - difT)
            #$$
            bLink = memory.currentBeliefLink
            difB = truth.getExpDifAbs(bTruth)
            bLink.decPriority(1-difB)
            bLink.decDurability(1-difB)
        dif = truth.getConfidence() - max(tTruth.getConfidence(), bTruth.getConfidence())
        priority = self.uor(dif, task.getPriority())
        durability = self.uor(dif, task.getDurability())
        quality = self.truthToQuality(truth)
        return BudgetValue(priority, durability, quality)
    #Links
    def distributeAmongLinks(self, b, n):
        priority = (b.getPriority / n ** (0.5))
        return BudgetValue(priority, b.getDurability, b.getQuality())
    #Concept
    def activate(self, concept, budget):
        quality = self.aveAri(concept.getQuality(), budget.getPriority())
        oldPri = concept.getPriority()
        priority = self.uor(oldPri, quality)
        durability = self.aveAri(concept.getDurability(), budget.getDurability, oldPri/priority)
        concept.setPriority(priority)
        concept.setDurability(durability)
        concept.setQuality(quality)
    #Bag Functions
    def forget(self, budget, forgetRate, relativeThreshold):
        quality = budget.getQuality() * relativeThreshold
        p = budget.getPriority() - quality
        if (p > 0):
            quality += p * budget.getDurability() ** (1.0/(forgetRate * p))
        budget.setPriority(quality)
    def merge(self, baseValue, adjustValue):
        baseValue.incPriority(adjustValue.getPriority())
        baseValue.setDurability(max(adjustVaue.getDurability(), baseValue.getDurability()))
        baseValue.setQuality(max(baseValue.getQuality(), adjustValue.getQuality()))
    #Task Derviation
    def forward(self, truth):
        return self.budgetInference(self.truthToQuality(truth), 1)
    def backward(self, truth):
        return self.budgetInference(self.truthToQuality(truth), 1)
    def backwardWeak(self, truth):
        return self.budgetInference(self.w2c(1) * self.truthToQuality(truth), 1)
    def compoundForward(self, truth, content):
        return self.budgetInference(self.truthToQuality(truth), content.getComplexity())
    def compoundBackward(self, content):
        return self.budgetInference(1, content.getComplexity())
    def compoundBackwardWeak(self, content):
        return self.budgetInference(self.w2c(1), content.getComplexity())
    def budgetInference(self, qual, complexity):
        #$$
        tLink = memory.currentTaskLink
        bLink = memory.currentBeliefLink
        priority = tLink.getPriority()
        durability = tLink.getDurability()
        quality = qual / (complexity ** (0.5))
        if (bLink != None):
            priority = self.aveAri(priority, bLink.getPriority)
            durability = aveAri(durability, bLink.getDurability())
            bLink.incPriority(quality)
        return BudgetValue(self.uand(priority, quality), self.uand(durability, quality), quality)
#CompositionalRules.java -- really long... grreeeeatttt
class CompositionalRules(object):
    def composeCompound(self, sentence, belief, index):
        if (not sentence.isJudgment()):
            return
        content1 = sentence.getContent()
        content2 = belief.getContent()
        if (content1.getClass() != content2.getClass()):
            return
        if (content1.getTemporalOrder() != content2.getTemporalOrder()):
            return
        component1 = content1.componentAt(1 - index)
        component2 = content2.componentAt(1 - index)
        component = content1.componentAt(1 - index)
        if ((isinstance(component1, CompoundTerm)) & component1.containAllComponents(component2)): #componeent1.CompoundTerm
            self.decomposeCompound(component1, component2, component, index, True)
            return
        elif (isinstance(component2, CompoundTerm) & component2.containAllComponents(component1)):
            self.decomposeCompound(component2, component1, component, index, False)
            return
        t1 = None
        t2 = None
        t3 = None
        t4 = None
        v1 = sentence.getTruth()
        v2 = belief.getTruth()
        if (index == 0):
            if (isinstance(content1, Inheritance)):
                t1 = intersectionInt.make(component1, component2)
                t2 = intersectionExt.make(component1, component2)
                t3 = differenceInt.make(component1, component2)
                t4 = differenceExt.make(component2, component1)
            elif (isinstance(content1, Implication)):
                t1 = disjunction.make(component1, component2)
                t2 = conjunction.make(component1, component2)
                t3 = conjunction.make(component1, negation.make(component2))
                t4 = conjunction.make(component2, negation.make(component1))
            self.processComposed(content1, component, t1, truthFunction.union(v1, v2))
            self.processComposed(content1, component, t2, truthFunctions.intersection(v1, v2))
            self.processComposed(content1, component, t3, truthFunctions.difference(v1, v2))
            self.processComposed(content1, component, t4, truthFunctions.difference(v2, v1))
            if(content1.isConstant()):
                self.introVarDepOuter(content1, content2, index)
        else:
            if (isinstance(content1, Inheritance)):
                t1 = intersectionExt.make(component1, component2)
                t2 = intersectionInt.make(component1, component2)
                t3 = differenceExt.make(component1, component2)
                t4 = differenceInt.make(component2, component1)
            elif (isinstance(content1, Implication)):
                t1 = conjunction.make(component1, component2)
                t2 = disjunction.make(component1, component2)
                t3 = disjunction.make(component1, negation.make(component2))
                t4 = disjunction.make(component2, negation.make(component1))
            self.processComposed(content1, t1, component, truthFunction.union(v1, v2))
            self.processComposed(content1, t2, component, truthFunctions.intersection(v1, v2))
            self.processComposed(content1, t3, component, truthFunctions.difference(v1, v2))
            self.processComposed(content1, t4, component, truthFunctions.difference(v2, v1))
            if(content1.isConstant()):
                self.introVarDepOuter(content1, content2, index)
    def processComposed(self, statement, subject, predicate, truth):
        if ((subject == None) or (predicate == None)):
            return
        content = statement.make(statement, subject, predicate)
        if ((content == None) or content.equals(statement) or content.equals(memory.currentBelief.getContent())):
            return
        budget = budgetFunctions.compoundForward(truth, content)
        memory.doublePremiseTask(budget, content, truth)
    def decomposeCompound(self, compound, component, term1, index, compoundTask):
        term2 = compoundTerm.reduceComponents(compound, component)
        if (term2 == None):
            return
        task = memory.currentTask
        sentence = task.getSentence()
        belief = memory.currentBelief
        oldContent = task.getContent()
        if (compoundTask):
            v1 = sentence.getTruth()
            v2 = belief.getTruth()
        else:
            v1 = belief.getTruth()
            v2 = sentence.getTruth()
        truth = None
        if (index == 0):
            content = statement.make(oldContent, term1, term2)
            if (content == None):
                return
            if (isinstance(oldContent, Inheritance)):
                if (isinstance(compound, IntersectionExt)):
                    truth = truthFunctions.reduceConjunction(v1, v2)
                elif (isinstance(compound, IntersectionInt)):
                    truth = truthFunctions.reduceDisjunction(v1, v2)
                elif (isinstance(compound, SetInt) & isinstance(component, SetInt)):
                    truth = truthFunctions.reduceConjunction(v1, v2)
                elif (isinstance(compound, SetExt) & isinstance(component, SetExt)):
                    truth = truthFunctions.reduceDisjunction(v1, v2)
                elif (isinstance(compound, DifferenceExt)):
                    if (compound.componentAt(0).equals(component)):
                        truth = truthFunctions.reduceDisjunction(v2, v1)
                    else:
                        truth = truthFunctions.reduceConjunction(v1, v2)
            elif (isinstance(oldContent, Implication)):
                if (isinstance(compound, Conjunction)):
                    truth = truthFunctions.reduceConjunction(v1, v2)
                elif (isinstance(compound, Disjunction)):
                    truth = truthFunctions.reduceDisjunction(v1, v2)
        else:
            content = statement.make(oldContent, term2, term1)
            if (content == None):
                return
            if (isinstance(oldContent, Inheritance)):
                if (isinstance(compound, IntersectionInt)):
                    truth = truthFunctions.reduceConjunction(v1, v2)
                elif (isinstance(compound, IntersectionExt)):
                    truth = truthFunctions.reduceDisjunction(v1, v2)
                elif (isinstance(compound, SetExt) & isinstance(component, SetExt)):
                    truth = truthFunctions.reduceConjunction(v1, v2)
                elif (isinstance(compound, SetInt) & isinstance(component, SetInt)):
                    truth = truthFunctions.reduceDisjunction(v1, v2)
                elif (isinstance(compound, DifferenceInt)):
                    if (compond.componentAt(1).equals(component)):
                        truth = truthFunctions.reduceDisjunction(v2, v1)
                    else:
                        truth = truthFunctions.reduceConjunction(v1, v2)
            elif (isinstance(oldContent, Implication)):
                if (isinstance(compound, Disjunction)):
                    truth = truthFunctions.reduceConjunction(v1, v2)
                elif (isinstance(compound, Conjunction)):
                    truth = truthFunctions.reduceDisjunction(v1, v2)
        budget = budgetFunctions.compoundForward(truth, content)
        memory.doublePremiseTask(budget, content, truth)
    def decomposeStatement(self, compound, component, compoundTask):
        task = memory.currentTask
        sentence = task.getSentence()
        if (not sentence.isJudgment()):
            return
        belief = memory.currentBelief
        content = compoundTerm.reduceComponents(compound.component)
        if (content == None):
            return
        if (compoundTask):
            v1 = sentence.getTruth()
            v2 = belief.getTruth()
        else:
            v1 = belief.getTruth()
            v2 = sentence.getTruth()
        truth = None
        if (isinstance(compound, Conjunction)):
            if (isinstance(sentence, Goal)):
                if (compoundTask):
                    truth = truthFunctions.reduceConjunction(v1, v2)
                else:
                    return
            elif (isinstance(sentence, Judgment)):
                truth = truthFunctions.reduceDisjunction(v1, v2)
        else:
            return
        budget = budgetFunctions.compoundForward(truth, content)
        memory.doublePremiseTask(budget, content, truth)
    def introVarDep(self, premise1, premise2, index):
        v1 = Variable("%s0()" % symbols.VARIABLE_TAG)
        v2 = Variable("%s0()" % symbols.VARIABLE_TAG)
        if (index == 0):
            state1 = statement.make(premise1, v1, premise1.getPredicate())
            state2 = statement.make(premise2, v2, premise2.getPredicate())
        else:
            state1 = statement.make(premise1, premise1.getSubject(), v1)
            state2 = statement.make(premise2, premise2.getSubject(), v2)
        content = conjunction.make(state1, state2)
        return content
    def introVarDepOuter(self, premise1, premise2, index):
        content = self.introVarDep(premise1, premise2, index)
        v1 = memory.currentTask.getSentence().getTruth()
        v2 = memory.currentBelief.getTruth()
        truth = truthFunctions.intersection(v1, v2)
        budget = budgetFunctions.compoundForward(truth, content)
        memory.doublePremiseTask(budget, content, truth)
    def introVarDepInner(self, compound, component, premise):
        if ((not isinstance(component, Statement)) or (component.getClass() != premise.getClass())):
            return
        premise1 = premise
        premise2 = component
        index = 0
        if (premise1.getSubject().equals(premise2.getSubject())):
            index = 0
        elif (premise1.getPredicate().equals(premise2.getPredicate())):
            index = 1
        else:
            return
        innerContent = self.introVarDep(premise1, premise2, index)
        if (innerContent == None):
            return
        task = memory.currentTask
        sentence = task.getSentence()
        belief = memory.currentBelief
        content = task.getContent()
        if (isinstance(compound, Implication)):
            content = statement.make(content, compound.componentAt(0), innerContent)
        elif (isinstance(compound, Conjunction)):
            content = compoundTerm.replaceComponent(compound, component, innerContent)
        truth = None
        if (isinstance(sentence, Goal)):
            truth = truthFunctions.intersection(belief.getTruth(), sentence.getTruth()) #JAVA: to be revised
        elif (isinstance(sentence, Judgment)):
            truth = truthFunctions.intersection(belief.getTruth(), sentence.getTruth())
        else:
            return
        budget = budgetFunctions.compoundForward(truth, content)
        memory.doublePremiseTask(budget, content, truth)
    def abdVarDepOuter(self, compound, component, compoundTask):
        content = compoundTerm.reduceComponents(compound, component)
        task = memory.currentTask
        sentence = task.getSentence()
        belief = memory.currentBelief
        v1 = sentence.getTruth()
        v2 = belief.getTruth()
        truth = None
        if (isinstance(sentence, Question)):
            if (compoundTask):
                budget = budgetFunctions.backward(v2)
            else:
                budget = budgetFunctions.backwardWeak(v2)
        else:
            if (isinstance(sentence, Goal)):
                if (compoundTask):
                    truth = truthFunctions.desireStrong(v1, v2)
                else:
                    truth = truthFunctinos.desireWeak(v1, v2)
            else:
                if (compoundTask):
                    truth = truthFunctions.existAnalogy(v1, v2)
                else:
                    truth = truthFunctions.existAnalogy(v2, v1)
            budget = budgetFunctions.compoundForward(truth, content)
        memory.doublePremiseTask(budget, content, truth)
#MatchingRules.java
class MatchingRules(object):
    def match(self, task, belief):
        sentence = task.getSentence()
        if (sentence.isJudgment()):
            self.revision(task, belief, True)
        else:
            self.trySolution(sentence, belief, None)
    #def update(self, newBelief, oldBelief): #JAVA: To be re-written
    
    def revision(self, task, belief, feedbackToLinks):
        judgment = task.getSentence()
        tTruth = judgment.getTruth()
        bTruth = belief.getTruth()
        truth = truthFunctions.revision(tTruth, bTruth)
        budget = budgetFunctions.revise(tTruth, bTruth, truth, task, feedbackToLinks)
        content = judgment.getContent
        memory.doublePremiseTask(budget, content, truth)
    def trySolution(self, problem, belief, task):
        oldBest = problem.getBestSolution()
        if (self.betterSolution(belief, oldBest, problem)):
            problem.setBestSolution(belief)
            budget = budgetFunctions.solutionEval(problem, belief, task)
            if (budget != None):
                memory.activatedTask(budget, belief, problem.isInput())
    def betterSolution(self, newSol, oldSol, problem):
        if (oldSol == None):
            return True
        else:
            return (newSol.solutionQuality(problem) > oldSol.solutionQuality(problem))
    def matchReverse(self):
        task = memory.currentTask
        belief = memory.currentBelief
        if (task.getContent().getTemporalOrder() != compoundTerm.temporalReverse(belief.getContent().getTemporalOrder())):
            return
        sentence = task.getSentence()
        if (sentence.isJudgment()):
            self.inferToSym(sentence, belief)
        else:
            self.conversion()
    def matchAsymSym(self, asym, sym, figure):
        order1 = asym.getContent().getTemporalOrder()
        order2 = asym.getContent().getTemporalOrder()
        order = compoundTerm.temporalInferenceWithFigure(order1, order2, figure)
        if (order == compoundTerm.TemporalOrder.UNSURE):
            return
        if (memory.currentTask.getSentence().isJudgment()):
            self.inferToAsym(asym, sym, order)
        else:
            return self.convertRelation()
    #2 premise inference rules
    def inferToSym(self, judgment1, judgment2):
        s1 = judgment1.getContent()
        s2 = judgment2.getContent()
        t1 = s1.getSubject()
        t2 = s1.getPredicate()
        if (isinstance(s1, Inheritance)):
            content = similarity.make(t1, t2)
        elif (isinstance(s1, ImplicationAfter)):
            content = equivalenceAfter.make(t1, t2)
        elif (isinstance(s1, ImplicationBefore)):
            content = equivalenceAfter.make(t2, t1)
        else:
            content = equivalence.make(t1, t2)
        value1 = judgment1.getTruth()
        value2 = judgment2.getTruth()
        truth = truthFunctions.intersection(value1, value2)
        budget = budgetFunctions.forward(truth)
        memory.doublePremiseTask(budget, content, truth)
    def inferToAsym(self, asym, sym, order):
        statement = asym.getContent()
        sub = statement.getPredicate()
        pre = statement.getSubject()
        content = statement.make(statement.sub, pre, order)
        truth = truthFunctions.reduceConjunction(sym.getTruth(), asym.getTruth())
        budget = budgetFunctions.forward(truth)
        memory.doublePremiseTask(budget, content, truth)
    # 1 premise inference rules
    def conversion(self):
        truth = truthFunctions.conversion(memory.currentBelief.getTruth())
        budget = budgetFunctions.forward(truth)
        memory.singlePremiseTask(truth, budget)
    def convertRelation(self):
        truth = memory.currentBelief.getTruth()
        if (memory.currentTask.getContent().isCommuntative()):# [.Statment].isCommuntative()???
            truth = truthFunctions.implied(truth)
        else:
            truth = truthFunctions.implying(truth)
        budget = budgetFunctions.forward(truth)
        memory.singlePremiseTask(truth, budget)
#TruthFunctions.java
class TruthFunctions(UtilityFunctions):
    def negation(self, v1):
        f = 1 - (v1.getFrequency())
        c = v1.getConfidence()
        return TruthValue(f, c)
    def conversion(self, v1):
        f1 = v1.getFrequency()
        c1 = v1.getConfidence()
        w = self.uand(f1, c1)
        c = self.w2c(w)
        return TruthValue(1, c)
    def contraposition(self, v1):
        f1 = v1.getFrequency()
        c1 = v1.getConfidence()
        w = self.uand(1-f1, c1)
        c = self.w2c(w)
        return TruthValue(0, c)
    def implying(self, v1):
        f1 = v1.getFrequency()
        c1 = v1.getConfidence()
        c = self.uand(f1, c)
    def implied(self, v1):
        f1 = v1.getFrequency()
        c1 = v1.getConfidence()
        c = w2c(c1)
        return TruthValue(f1, c)
    def negImply(self, v1):
        return self.negation(self.implying(v1))
    def revision(self, v1, v2):
        f1 = v1.getFrequency()
        f2 = v2.getFrequency()
        c1 = v1.getConfidence()
        c2 = v2.getConfidence()
        w1 = c1 / (1 - c1)
        w2 = c2 / (1 - c2)
        f = (w1 * f1 + w2 * f2) / (w1 + w2)
        c = (w1 + w2) / (w1 + w2 + 1)
        return TruthValue(f, c)
    def deduction(self, v1, v2):
        f1 = v1.getFrequency()
        f2 = v2.getFrequency()
        c1 = v1.getConfidence()
        c2 = v2.getConfidence()
        f = self.uand(f1, f2)
        c = self.uand(c1, c2, f)
        return TruthValue(f, c)
    def abduction(self, v1, v2):
        f1 = v1.getFrequency()
        f2 = v2.getFrequency()
        c1 = v1.getConfidence()
        c2 = v2.getConfidence()
        w = self.uand(f2, c1, c2)
        c = self.w2c(w)
        return TruthValue(f1, c)
    def induction(self, v1, v2):
        return self.abduction(v2, v1)
    def exemplification(self, v1, v2):
        f1 = v1.getFrequency()
        f2 = v2.getFrequency()
        c1 = v1.getConfidence()
        c2 = v2.getConfidence()
        w = self.uand(f1, f2, c1, c2)
        c = self.w2c(w)
        return TruthValue(1, c)
    def comparison(self, v1, v2):
        f1 = v1.getFrequency()
        f2 = v2.getFrequency()
        c1 = v1.getConfidence()
        c2 = v2.getConfidence()
        f0 = self.uand(f1, f2)
        if (f0 == 0):
            f = 0
        else:
            f = self.uand(f1, f2) / f0
        w = self.uand(f0, c1, c2)
        c = self.w2c(w)
        return TruthValue(f, c)
    def analogy(self, v1, v2):
        f1 = v1.getFrequency()
        f2 = v2.getFrequency()
        c1 = v1.getConfidence()
        c2 = v2.getConfidence()
        f0 = self.uor(f1, f2)
        if (f0 == 0):
            f = 0
        else:
            f = self.uand(f1, f2) / f0
        w = self.uand(f0, c1, c2)
        c = self.w2c(w)
        return TruthValue(f, c)
    def resemblance(self, v1, v2):
        f1 = v1.getFrequency()
        f2 = v2.getFrequency()
        c1 = v1.getConfidence()
        c2 = v2.getConfidence()
        f = self.uand(f1, f2)
        c = self.uand(c1, c2, self.uor(f1, f2))
        return TruthValue(f, c)
    def desireStrong(self, v1, v2):
        f1 = v1.getFrequency()
        f2 = v2.getFrequency()
        c1 = v1.getConfidence()
        c2 = v2.getConfidence()
        f = self.uand(f1, f2)
        c = self.uand(c1, c2, f2)
        return TruthValue(f, c)
    def desireWeak(self, v1, v2):
        f1 = v1.getFrequency()
        f2 = v2.getFrequency()
        c1 = v1.getConfidence()
        c2 = v2.getConfidence()
        f = self.uand(f1, f2)
        c = self.uand(c1, c2, f2, self.w2c(1.0))
        return TruthValue(f, c)
    def desireDed(self, v1, v2):
        f1 = v1.getFrequency()
        f2 = v2.getFrequency()
        c1 = v1.getConfidence()
        c2 = v2.getConfidence()
        f = self.uand(f1, f2)
        c = self.uand(f, c1, c2)
        return TruthValue(f, c)
    def desireInd(self, v1, v2):
        f1 = v1.getFrequency()
        f2 = v2.getFrequency()
        c1 = v1.getConfidence()
        c2 = v2.getConfidence()
        w = self.uand(f2, c1, c2)
        c = self.w2c(w)
        return TruthValue(f1, c)
    def union(self, v1, v2):
        f1 = v1.getFrequency()
        f2 = v2.getFrequency()
        c1 = v1.getConfidence()
        c2 = v2.getConfidence()
        f = self.uor(f1, f2)
        c = self.uor(self.uand(f1, c1), self.uand(f2, c2)) + self.uand(1 - f1, 1 - f2, c1, c2)
        return TruthValue(f, c)
    def intersection(self, v1, v2):
        f1 = v1.getFrequency()
        f2 = v2.getFrequency()
        c1 = v1.getConfidence()
        c2 = v2.getConfidence()
        f = self.uand(f1, f2)
        c = self.uor(self.uand(1 - f1, c1), self.uand(1-f2, c2)) + self.uand(f1,f2,c1,c2)
        return TruthValue(f, c)
    def difference(self, v1, v2):
        v0 = self.negation(v2)
        return self.intersection(v1, v0)
    def reduceDisjunction(self, v1, v2):
        v0 = self.intersection(v1, self.negation(v2))
        return self.implying(v0)
    def reduceConjunction(self, v1, v2):
        v0 = self.intersection(self.negation(v1), v2)
        return self.negation(self.implying(v0))
    def reduceConjunctionNeg(self, v1, v2):
        return self.reduceConjunction(v1, self.negation(v2))
    def existAnalogy(self, v1, v2):
        return self.abduction(v1, v2)
        
#UtilityFunctions.java -- see above
#/gui
#TODO: Finish InferenceWindow!
#InferenceWindow.java
class InferenceWindow(object):
    def __init__(self):
        #This class is just a really quick
        #mockup to get the basic functions
        #setup so that we can test-run it.
        self.text = ""
        self.visible = False
    def setVisible(self, v):
        self.visible = v
    def isVisible(self):
        return self.visible
    def append(self, s):
        text += s
    def clear(self):
        text = ""
        
#/io
#Record.java
class Record(object):
    def __init__(self):
        self.window = InferenceWindow()
        self.isReporting = False
        self.window.clear()
    def show(self):
        self.window.setVisible(True)
    def play(self):
        self.isReporting = True
    def stop(self):
        self.isReporting = False
    def append(self, s):
        if(self.isReporting):
            self.window.append(s)
#Symbols.java
class Symbols(object):
    def __init__(self):
        self.JUDGMENT_MARK = "."
        self.QUESTION_MARK = "?"
        self.GOAL_MARK = "!"
        self.BUDGET_VALUE_MARK = "$"
        self.TRUTH_VALUE_MARK = "%"
        self.VALUE_SEPARATOR = ";"
        self.VARIABLE_TAG = "#"
        self.QUERY_VARIABLE_TAG = "?"
        self.OPERATOR_TAG = "^"
        self.COMPOUND_TERM_OPENER = "("
        self.COMPOUND_TERM_CLOSER = ")"
        self.STATEMENT_OPENER = "<"
        self.STATEMENT_CLOSER = ">"
        self.SET_EXT_OPENER = "{"
        self.SET_EXT_CLOSER = "}"
        self.SET_INT_OPENER = "["
        self.SET_INT_CLOSER = "]"
        self.ARGUMENT_SEPARATOR = ","
        self.IMAGE_PLACE_HOLDER = "_"
        self.INTERSECTION_EXT_OPERATOR = "&"
        self.INTERSECTION_INT_OPERATOR = "|"
        self.DIFFERENCE_EXT_OPERATOR = "-"
        self.DIFFERENCE_INT_OPERATOR = "~"
        self.PRODUCT_OPERATOR = "*"
        self.IMAGE_EXT_OPERATOR = "/"
        self.IMAGE_INT_OPERATOR = "\\"
        self.INHERITANCE_RELATION = "-->"
        self.SIMILARITY_RELATION = "<->"
        self.INSTANCE_RELATION = "{--"
        self.PROPERTY_RELATION = "--]"
        self.INSTANCE_PROPERTY_RELATION = "{-]"
        self.IMPLICATION_RELATION = "==>"
        self.EQUIVALENCE_RELATION = "<=>"
        self.IMPLICATION_AFTER_RELATION = "=/>"
        self.IMPLICATION_BEFORE_RELATION = "=\\>"
        self.IMPLICATION_WHEN_RELATION = "=|>"
        self.EQUIVALENCE_AFTER_RELATION = "</>"
        self.EQUIVALENCE_WHEN_RELATION = "<|>"
        self.Base_opener = " {"
        self.Base_closer = "} "
        self.Base_separator = ";"
        self.Base_separator0 = ": "
        self.LinkToComponent_at1 = " @("
        self.LinkToComponent_at2 = ") _ "
        self.LinkToCompound_at1 = " _ @("
        self.LinkToCompound_at2 = ") "
#StringParser.java
class StringParser(Symbols):
    class InvalidInputException(Exception):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return self.value
    def trim(self, s):
        return s.lstrip().rstrip()
    def parseTask(self, s):
        try:
            budgetString = self.getBudgetString(s)
            truthString = self.getTruthString(s)
            s = self.trim(s)
            last = len(s) - 1
            punc = s[last]
            truth = self.parseTruth(truthString, punc)
            budget = self.parseBudget(budgetString, punc, truth)
            content = self.parseTerm(str[0:last])
            base = None
            if (punc != self.QUESTION_MARK):
                base = Base()
            sentence = sentence.make(content, punc, truth, base)
            if (sentence == None):
                raise self.InvalidInputException("invalid sentence")
            sentence.setInput()
            task = Task(sentence, budget)
            return task
        except InvalidInputException, e:
            print "!!! INVALID INPUT: %s --- %s" % (s, e)
            return None
    def getBudgetString(self, s):
        if (s[0] != self.BUDGET_VALUE_MARK):
            return None
        i = s.index(self.BUDGET_VALUE_MARK, 2)
        if (i < 0):
            raise self.InvalidInputException("missing budget closer")
        budgetString = self.trim(s[1:i])
        if (len(budgetString) == 0):
            raise self.InvalidInputException("empty budget")
        return budgetString
    def getTruthString(self, s):
        last = len(s) - 1
        if(s[last] != self.TRUTH_VALUE_MARK):
            return None
        first = s.index(self.TRUTH_VALUE_MARK)
        if(first == last):
            raise self.InvalidInputException("missing truth mark")
        truthString = self.trim(s[first+1:last])
        if(len(truthString) == 0):
            raise self.InvalidInputException("empty truth")
        return truthString
    def parseTruth(self, s, t):
        if(t == self.QUESTION_MARK):
            return None
        frequency = 1.0
        confidence = parameters.DEFAULT_JUDGMENT_CONFIDENCE
        if (s != None):
            i = s.index(self.VALUE_SEPARATOR)
            if (i < 0):
                frequency = float(s)
            else:
                frequency = float(s[0:i])
                confidence = float(s[i+1:])
        return TruthValue(frequency, confidence)
    def parseBudget(self, s, punc, truth):
        switch = {self.JUDGMENT_MARK: (parameters.DEFAULT_JUDGMENT_PRIORITY, parameters.DEFAULT_JUDGMENT_DURABILITY),
                  self.GOAL_MARK: (parameters.DEFAULT_GOAL_PRIORITY, parameters.DEFAULT_GOAL_DURABILITY),
                  self.QUESTION_MARK: (parameters.DEFAULT_QUESTION_PRIORITY, parameters.DEFAULT_QUESTION_DURABILITY),
                 }
        if (not switch.has_key(punc)):
            raise self.InvalidInputException("unknown punctuation")
        priority, durability = switch[punc]
        if (s != None):
            i = s.index(self.VALUE_SEPARATOR)
            if (i < 0):
                priority = float(s)
            else:
                priority = float(s[0:i])
                durability = float(s[i+1:])
        quality = 1
        if (punc != self.QUESTION_MARK):
            quality = budgetFunctions.truthToQuality(truth)
        return BudgetValue(priority, durability, quality)
    def parseTerm(self, s):
        s = self.trim(s)
        if (len(s) == 0):
            raise self.InvalidInputException("missing content")
        t = memory.nameToListerTerm(s)
        if (t != None):
            return t
        index = len(s) - 1
        first = s[0]
        last = s[index]
        #I could do some bizzare kludge, but this is more readable
        if (first == self.COMPOUND_TERM_OPENER):
            if (last == self.COMPOUND_TERM_CLOSER):
                return self.parseCompoundTerm(s[1:index])
            else:
                raise self.InvalidInputException("missing CompoundTerm closer")
        elif (first == self.SET_EXT_OPENER):
            if (last == self.SET_EXT_CLOSER):
                return setExt.make(self.parseArguments(s[1:index] + self.ARGUMENT_SEPARATOR))
            else:
                raise self.InvalidInputException("missing ExtensionSet closer")
        elif (first == self.SET_INT_OPENER):
            if (last == self.SET_INT_CLOSER):
                return setInt.make(self.parseArguments(s[1:index] + self.ARGUMENT_SEPARATOR))
            else:
                raise self.InvalidInputException("missing IntensionSet closer")
        elif (first == self.STATEMENT_OPENER):
            if (last == self.STATEMENT_CLOSER):
                return self.parseCompoundTerm(s[1:index])
            else:
                raise self.InvalidInputException("missing CompoundTerm closer")
        else:
            return self.parseSimpleTerm(s)
    def parseSimpleTerm(self, s):
        s = self.trim(s)
        if (len(s) == 0):
            raise self.InvalidInputException("missing term")
        if (s.index(" ") > 0):
            raise self.InvalidInputException("invalid term")
        prefix = s[0]
        if ((prefix == self.VARIABLE_TAG) or (prefix == self.QUERY_VARIABLE_TAG)):
            term = Variable(s)
        else:
            term = Term(s)
        return term
    def parseStatement(self, s):
        s = self.trim(s)
        i = self.topRelations(s)
        if (i < 0):
            raise self.InvalidInputException("invalid statement")
        relation = s[i:i+3]
        subject = self.parseTerm(s[0:i])
        predicate = self.parseTerm(s[i+3:])
        t = statement.make(relation, subject, predicate)
        if (t == None):
            raise self.InvalidInputException("invalid statement")
        return t
    def parseCompoundTerm(self, s):
        s = self.trim(s)
        firstSeparator = s.index(self.ARGUMENT_SEPARATOR)
        op = self.trim(s[0:firstSeparator])
        if (not compoundTerm.isOperator(op)):
            raise self.InvalidInputException("unknown operator: %s" % op)
        arg = self.parseArguments(s[firstSeparator+1:] + self.ARGUMENT_SEPARATOR)
        t = compoundTerm.mark(op, arg)
        if (t == None):
            raise self.InvalidInputException("invalid compound term")
        return t
    def parseArguments(self, s):
        s = self.trim(s)
        l = []
        start = 0
        end = 0
        while (end < len(s)-1):
            end = self.nextSeparator(s, start)
            t = self.parseTerm(s[start:end])
            l.append(t)
            start = end + 1
        if (len(l) == 0):
            raise self.InvalidInputException("null argument")
    def nextSeparator(self, s, first):
        levelCounter = 0
        i = first
        while (i < len(s)-1):
            if (self.isOpener(s, i)):
                levelCounter += 1
            elif (self.isCloser(s, i)):
                levelCounter -= 1
            elif (s[i] == self.ARGUMENT_SEPARATOR):
                if (levelCounter == 0):
                    break
            i += 1
        return i
    def topRelation(self, s):
        levelCounter = 0
        i = 0
        while (i < len(s)-3):
            if ((levelCounter == 0) and (statement.isRelation(s[i:i+3]))):
                return i
            if (self.isOpener(s, i)):
                levelCounter += 1
            elif (self.isCloser(s, i)):
                levelCounter -= 1
            i += 1
        return -1
    def isOpener(self, s, i):
        c = s[i]
        b = ((c == self.COMPOUND_TERM_OPENER) or
            (c == self.SET_EXT_OPENER) or
            (c == self.SET_INT_OPENER) or
            (c == self.STATEMENT_OPENER))
        if (not b):
            return False
        if (i+3 <= len(s) and statement.isRelation(s[i:i+3])):
            return False
        return True
    def isCloser(self, s, i):
        c = s[i]
        b = ((c == self.COMPOUND_TERM_CLOSER) or
            (c == self.SET_EXT_CLOSER) or
            (c == self.SET_INT_CLOSER) or
            (c == self.STATEMENT_CLOSER))
        if (not b):
            return False
        if (i >= 2 and statement.isRelation(s[i-2:i+1])):
            return False
        return True
#/main
#NARS.java
class NARS(object):
    def __init__(self):
        self.INFO = "     Open-NARS     Version 1.0.0     January 2008  \n"
        self.WEBSITE = " Open-NARS website:  http://code.google.com/p/open-nars/ \n"
        self.standAlone = True
        center.start()
        #We don't need a start() function
    def run(self):
        #TODO: Create run function (for now, it's just walk)
        center.tick()
    def isStandAlone(self):
        return self.standAlone
    def getAppletInfo(self):
        return self.INFO      
        
#Center.java
class Center(object):
    #should start() be __init__?
    #Probably not
    def __init__(self):
        #Record, Base, Memory
        self.stoper = 0
    def start(self):
        #self.mainWindow = MainWindow()
        #self.inputWindow = InputWindow()
        #$$$
        self.base = Base()
        self.reset()
    def reset(self):
        self.stoper = 0
        self.clock = 0
        #$$$ -- hmmm....
        #self.base.init()
        #memory.init()
        running = False
    def setStoper(self, i):
        if (i < 0):
            self.running = True
            self.stoper = 0
        else:
            self.running = False
            self.stoper = 0
    def tick(self):
        if (self.stoper == 0):
            self.stoper = inputWindow.getInput()
        if (self.running or (self.stoper > 0)):
            self.clock += 1
            record.append(" --- " + self.clock + " ---\n")
            self.mainWindow.tickTimer()
            memory.cycle()
            if (self.stoper > 0):
                stoper -= 1
    def showInputWindow(self):
        inputWindow.setVisible(True)
#Memory.java
class Memory(object):
    def __init__(self):
        self.concepts = ConceptBag()
        self.newTasks = []
        self.taskBuffer = TaskBag()
    def nameToListedTerm(self, name):
        concept = self.concepts.get(name)
        if (concept != None):
            return concept.getTerm()
        return self.operators.get(name)
    def nameToOperator(self, name):
        return self.operators.get(name)
    def nameToConcept(self, name):
        return self.concepts.get(name)
    def termToConcept(self, term):
        return self.nameToConcept(term.getName())
    def getConcept(self, term):
        n = term.getName()
        concept = self.concepts.get(n)
        if (concept == None):
            concept = Concept(term)
        return concept
    def activateConcept(self, c, b):
        if(self.concepts.contains(c)):
            self.concepts.pickOut(c.getKet())
            budgetFunctions.activate(c, b)
            self.concepts.putBack(c)
        else:
            budgetFunctions.activate(c, b)
            self.concepts.putIn(c)
            
    def inputTask(self, n):
        task = StringParser.parseTask(n)
        if (task != None):
            if (nars.isStandAlone()):
                record.append("not not not  Input: %s\n" % task)
            if (task.aboveThreshold()):
                self.report(task.getSentence(), True)
                self.newTasks.add(task)
                self.taskBuffer.refresh()
            else:
                record.append("not not not  Ignored: %s\n" % task)
    def derivedTask(self, task):
        record.append("not not not  Derived: %s\n" % str(task))
        if (task.aboveThreshold()):
            budget = task.getBudget().singleValue()
            minSilent = center.mainWindow.silentW.value() / 100.0
            if (budget > minSilent):
                self.report(task.getSentence(), False)
            self.newTasks.add(task) 
            self.taskBuffer.refresh()
        else:
            record.append("not not not  Ignored: %s\n" % task)
    def executedTask(self, task):
        record.append("not not not  Executed: %s\n" % str(task))
        budget = task.getBudget().singleValue()
        minSilent = center.mainWindow.silentW.value() / 100.0
        if (budget > minSilent):
            self.report(task.getSentence(), False)
    def activatedTask(self, budget, sentence, isInput):
        task = Task(sentence, budget)
        if (nars.isStandAlone()):
            record.append("not not not  Activated: %s\n" % str(task))
        self.newTasks.add(task)
        self.taskBuffer.refresh()
    #New Task Building
    def doublePremiseTask(self, budget, content, truth):
        newSentence = self.sentence.make(self.currentTask.getSentence(), content, truth, self.currentBase)
        newTask = Task(newSentence, budget)
        self.derivedTask(newTask)
    def singlePremiseTask(self, budget, content=None, truth=None):
        if (content == None):
            content = self.currentTask.getContent()
        sentence = self.currentTask.getSentence()
        newSentence = self.sentence.make(sentence, content, truth, sentence.getBase())
        newTask = Task(newSentence, budget)
        newTask.setStructual()
        self.derivedTask(newTask)
    #System Working Cycle
    def cycle(self):
        self.processTask()
        self.processConcept()
    def processTask(self):
        for task in self.newTasks:
            if (task.getSentence().isInput() or (self.termToConcept(task.getContent()) != None)):
                self.immediateProcess(task)
            else:
                self.taskBuffer.putIn(task)
        self.newTasks = []
        task = taskBuffer.takeOut()
        if (task != None):
            immediateProcess(task)
    def processConcept(self):
        currentConcept = self.concepts.takeOut()
        if (currentConcept != None):
            self.currentTerm = currentConcept.getTerm()
            record.append(" * Selected Concept: %s\n" % self.currentTerm)
            self.concepts.putBack(currentConcept)
            currentConcept.fire()
            self.taskBuffer.refresh()
    # Task/belief insertion
    def immediateProcess(self, task):
        if (nars.isStandAlone()):
            record.append("not not not  Accept: %s\n" % str(task))
        content = task.getContent()
        if (content.isConstant()):
            c = self.getConcept(content)
            c.directProcess(task)
        if (task.aboveThreshold()):
            self.coninuedProcess(task, content)
    def continuedProcess(self, task, content):
        budget = task.getBudget()
        c1 = None
        if (content.isConstant()):
            c1 = self.getConcept(content)
            tLink = TaskLink(task, None, budget)
            c1.insertTaskLink(tLink)
        if (isinstance(content,CompoundTerm)):
            if (c1 == None):
                cLinks = CompoundTerm.prepareComponentLinks()
            else:
                cLinks = c1.getTermLinks()    
            subBudget = budgetFunctions.distributeAmongLinks(budget, len(cLinks))
            if (not subBudget.aboveThreshold()):
                return
            for cLink in cLinks:
                component = cLink.getTarget()
                c2 = getConcept(component)
                if (not (task.isStructual() & (cLink.getType() == TermLink.TRANSFORM))):
                    tLink = TaskLink(task, cLink, subBudget)
                    c2.insertTaskLink(tLink)
    #Display
    def conceptsStartPlay(self, s):
        self.concepts.startPlay(s)
    def taskBufferStartPlay(self, s):
        self.taskBuffer.startPlay(s)
    def resultsToString(self):
        s = " New Tasks: \n"
        for newTask in self.newTasks:
            s = "%s%s\n" % (s, str(newTask))
        s = "%s\n Task Buffer: \n" %s
        return s
    def report(self, sentence, i):
        if (i):
            s = "IN"
        else:
            s = "OUT"
        s = " %s: %s\n" % (s, sentence.str2())
        center.mainWindow.post(s)

#Parameters.java
class Parameters(object):
    def __init__(self):
        self.CONCEPT_DEFAULT_FORGETTING_CYCLE = 3
        self.TASK_DEFAULT_FORGETTING_CYCLE = 10
        self.BELIEF_DEFAULT_FORGETTING_CYCLE = 50
        self.SILENT_LEVEL = 100
        self.NEAR_FUTURE = 1
        self.DEFAULT_JUDGEMENT_CONFIDENCE = 0.90
        self.DEFAULT_JUDGEMENT_PRIORITY = 0.80
        self.DEFAULT_JUDGEMENT_DURABILITY = 0.80
        self.DEFAULT_GOAL_PRIORITY = 0.90
        self.DEFAULT_GOAL_DURABILITY = 0.70
        self.DEFAULT_QUESTION_PRIORITY = 0.90
        self.DEFAULT_QUESTION_DURABILTY = 0.70
        self.DEFAULT_COMPONENT_PRIORITY_RATE = 0.70
        self.BAG_LEVEL = 100
        self.BAG_THRESHOLD = 10
        self.COLD_TASK_DELAY_STEPS = 10
        self.NEW_TASK_DEFAULT_FORGETTING_CYCLE = 1
        self.DEFAULT_QUALITY_UPDATE_RATE = 0.01
        self.MAX_TAKE_OUT_K_LINK = 10
        self.MAX_TAKE_OUT_BELIEF = 5
        self.CONCEPT_BAG_SIZE = 1000
        self.TASK_BUFFER_SIZE = 20
        self.TASK_BAG_SIZE = 20
        self.BELIEF_BAG_SIZE = 100
        self.MAXMUM_LABEL_RECORD_LENGTH = 16
        self.TASK_INFERENCE_RECORD_LENGTH = 20
        self.MAXMUM_BELIEF_LENGTH = 8
        self.MAXMUM_GOALS_LENGTH = 5
        self.LOAD_FACTOR = 0.50
#/operation
#Operator.java
class Operator(Term):
    def setOperators(self):
        table = {"^go-to": GoTo("^go-to"),
                      "^pick": Pick("^pick"),
                      "^open": Open("^open"),}
        return table
#GoTo.java
class GoTo(Operator):
    def execute(self, task):
        print "EXECUTE in %s %s" % (self.name, task)
        return None
#Open.java
class Open(Operator):
    def execute(self, task):
        print "EXECUTE in %s %s" % (self.name, task)
        return None
#Pick.java
class Pick(Operator):
    def execute(self, task):
        print "EXECUTE in %s %s" % (self.name, task)
        return None
#/storage
#Bag.java:
class Bag(Item):
    def __init__(self):
        self.TOTAL_LEVEL = parameters.BAG_LEVEL
        self.THRESHOLD = parameters.BAG_THRESHOLD
        self.RELATIVE_THRESHOLD = self.THRESHOLD / self.TOTAL_LEVEL
        self.LOAD_FACTOR = parameters.LOAD_FACTOR
        self.DISTRIBUTOR = Distributor(self.TOTAL_LEVEL)
        self.nameTable = []
        #HashMaps are like dictionaries, right?
        self.itemTable = {}
        self.capacity = self.capacity()
        self.mass = 0
        self.levelIndex = self.capacity % self.TOTAL_LEVEL
        self.currentLevel = self.TOTAL_LEVEL - 1
        self.currentCounter = 0
        self.showing = False
    def capacity(self):
        return 0
    def forgetRate(self):
        return 0
    def averagePriority(self):
        if (len(self.nameTable) == 0):
            return 0.01
        f = self.mass / (self.nameTable.size() * self.TOTAL_LEVEL * 1.0)
        if (f > 1):
            return 1.0
        return f
    def contains(self, it):
        for k, v in self.nameTable.iteritems():
            if (v == it):
                return True
    def get(self, key):
        if (self.nameTable.has_key(key)):
            return self.nameTable[key]
    def putIn(self, newItem):
        newKey = newItem.getKey()
        if (not self.nameTable.has_key(newKey)):
            oldItem = self.nameTable[newKey]
            self.outOfBase(oldItem)
            newItem.merge(oldItem)
        self.nameTable[newKey] = newItem
        overflowItem = self.intoBase(newItem)
        if (overflowItem != None):
            overflowKey = overflowItem.getKey()
            self.nameTable.remove(overflowKey)
    def putBack(self, oldItem):
        budgetFunctions.forget(oldItem.getBudget(), self.forgetRate(), self.RELATIVE_THRESHOLD)
        self.putIn(oldItem)
    def takeOut(self):
        if (self.mass == 0):
            return
        if (self.emptyLevel(self.currentLevel) or (self.currentCounter == 0)):
            self.currentLevel = self.DISTRIBUTOR.pick(self.levelIndex)
            self.levelIndex = self.DISTRIBUTOR.next(self.levelIndex)
            while (self.emptLevel(self.currentLevel)):
                self.currentLevel = self.DISTRIBUTOR.pick(self.levelIndex)
                self.levelIndex = self.DISTRIBUTOR.next(self.levelIndex)
            if (self.currentLevel < self.THRESHOLD):
                self.currentCounter = 1
            else:
                self.currentCounter = len(self.itemTable[self.currentLevel])
        selected = self.takeOutFirst(self.currentLevel)
        self.currentCounter -= 1
        self.nameTable.remove(selected.getKey())
        self.refresh()
        return selected
    def pickOut(self, key):
        picked = self.nameTable.get(key)
        if (picked != None):
            self.outOfBase(picked)
            del self.nameTable[key]
        return picked
    def emptyLevel(self, n):
        if (len(self.itemTable) > n):
            return True
        else:
            return self.itemTable[n].isEmpty()
    def getLevel(item): 
        from math import ceil
        fl = item.getPriority() * self.TOTAL_LEVEL * 1.0
        level = ceil(fl) - 1
        if (level > 0):
            return level
        return 0
    def intoBase(self, newItem):
        oldItem = None
        inLevel = self.getLevel(newItem)
        if (len(self.nameTable) > self.capacity):
            outLevel = 0
            while (self.emptyLevel(outLevel)):
                outLevel += 1
            if (outLevel > inLevel):
                return newItem
            else:
                oldItem = self.takeOutFirst(outLevel)
        if (len(self.itemTable) > inLevel):
            self.itemTable[inLevel] = []
        self.itemTable[inLevel].append(newItem)
        self.mass += (inLevel + 1)
        self.refresh()
        return oldItem
    def takeOutFirst(self, level):
        #selected = self.itemTable[level][0]
        selected = self.itemTable[level].pop(0)
        self.mass -= (level + 1)
        self.refresh()
        return selected
    def outOfBase(self, oldItem):
        level = self.getLevel(oldItem)
        self.itemTable[level].remove(oldItem)
        self.mass -= (level + 1)
        self.refresh()
    def startPlay(self, title):
        self.window = BagWindow(self, title)
        self.showing = True
        self.window.post(str(self))
    def play(self):
        self.showing = True
        self.window.post(str(self))
    def refresh(self):
        if(self.showing):
            self.window.post(str(self))
    def stop(self):
        self.showing = False
    def __str__(self):
        buf = ""
        r = self.window.showLevel - self.TOTAL_LEVEL
        for i in range(r):
            i += self.TOTAL_LEVEL
            if (not self.emptyLevel(i-1)):
                buf = "%s\n --- Level %s:\n" % (buf, str(i))
            for j in itemTable[i-1]:
                buf = "%s%s\n" % (buf, j)
        return buf
#ConceptBag.java
class ConceptBag(Bag):
    def __init__(self):
        super(ConceptBag, self).__init__()
    def capacity(self):
        return parameters.CONCEPT_BAG_SIZE
    def forgetRate(self):
        return mainWindow.forgetCW.value()   
#Distributor.java
class Distributor(object):
    def __init__(self, r):
        self.order = []
        self.capacity = (r * (r + 1)) / 2
        for x in range(self.capacity):
            self.order.append(-1)
        tmp = range(r)
        tmp.reverse()
        tmp.pop()
        index = 0
        for rank in tmp:
            for time in range(rank):
                index = ((self.capacity / rank) + index) % self.capacity
                while (self.order[index] >= 0):
                    index = (index + 1) % self.capacity
                self.order[index] = rank - 1
    def pick(self, index):
        return self.order[index]
    def next(self, index):
        return (index + 1) % self.capacity
#TaskBag.java
class TaskBag(Bag):
    def __init__(self):
        self.defaultForgetRate = parameters.NEW_TASK_DEFAULT_FORGETTING_CYCLE
        super(TaskBag, self).__init__()
    def capacity(self):
        return parameters.TASK_BUFFER_SIZE
    def forgetRate(self):
        return mainWindow.forgetTW.value()
    def __str__(self):
        return memory.resultsToString() + super(TaskBag, self).__str__(self)
class TaskLinkBag(Bag):
    def capacity(self):
        return parameters.TASK_BAG_SIZE
    def forgetRate(self):
        return mainWindow.forgetTW.value()
class TermLinkBag(Bag):
    def __init__(self):
        self.maxTakeOut = parameters.MAX_TAKE_OUT_K_LINK
        super(TermLinkBag, self).__init__()
    def capacity(self):
        return parameters.BELIEF_BAG_SIZE
    def forgetRate(self):
        return mainWindow.forgetBW.value()

#I told you you shouldn't run this! 
if __name__ == '__main__': 
    print "DO NOT RUN! THIS DOES NOTHING" #__doc__

parameters = Parameters()
memory = Memory()
center = Center()
record = Record()
symbols = Symbols()

budgetFunctions = BudgetFunctions()
ruleTables = RuleTables()
truthFunctions = TruthFunctions()
utilityFunctions = UtilityFunctions()
#structualRules = StructualRules()
#syllogisticRules = SyllogisticRules()
nars = NARS()
